package com.nb.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.nb.entity.*;
import com.nb.mapper.*;
import com.nb.service.AuthService;
import com.nb.vo.UserInfoVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class AuthServiceImpl implements AuthService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Autowired
    private SysAclMapper sysAclMapper;
    @Override
    public UserInfoVO getAuthInfo() {
        UserInfoVO userInfoVO = new UserInfoVO();
        //获取用户基本信息
        User user = userMapper.selectOneById(StpUtil.getLoginIdAsLong());
        if (user == null) {
            throw new RuntimeException("当前用户不存在");
        }
        userInfoVO.setUsername(user.getUsername());
        userInfoVO.setUserId(user.getId());
        userInfoVO.setRealName(user.getRealName());
        Long deptId = user.getDeptId();
        userInfoVO.setDeptId(deptId);
        //获取用户部门名称
        if (deptId != null) {
            Dept dept = deptMapper.selectOneById(user.getDeptId());
            if (dept != null) {
                userInfoVO.setDeptName(dept.getName());
            }
        }
        //获取用户角色列表
        List<String> roleCodeList = roleMapper.selectRoleCodeListByUserId(user.getId());
        userInfoVO.setRoles(roleCodeList);

        //获取用户权限列表
        List<Long> aclIdList = roleMapper.selectAclIdListByRoleCodeList(roleCodeList);
        //获取用户菜单列表
        QueryWrapper queryWrapper = QueryWrapper.create().in("acl_id", aclIdList);
        List<SysMenuEntity> menuList = sysMenuMapper.selectListByQuery(queryWrapper);
        //处理菜单列表，根据parent_id将菜单列表转换为树结构
        List<UserInfoVO.Menu> treeMenuList = buildMenuTree(menuList);
        userInfoVO.setMenuList(treeMenuList);
        return userInfoVO;
    }

    public static List<UserInfoVO.Menu> buildMenuTree(List<SysMenuEntity> menuList) {
        // 创建结果列表
        List<UserInfoVO.Menu> result = new ArrayList<>();

        // 创建菜单ID到VO的映射
        Map<Long, UserInfoVO.Menu> menuMap = new HashMap<>();

        // 首先将所有菜单转换为VO对象并存入map
        for (SysMenuEntity menu : menuList) {
            UserInfoVO.Menu voMenu = new UserInfoVO().new Menu();
            voMenu.setId(menu.getId());
            voMenu.setName(menu.getName());
            voMenu.setPath(menu.getPath());

            // 处理component字段：path去掉开头的/后，第一个字母大写
            if (menu.getPath() != null && !menu.getPath().isEmpty()) {
                String path = menu.getPath().startsWith("/") ? menu.getPath().substring(1) : menu.getPath();
                if (!path.isEmpty()) {
                    String component = path.substring(0, 1).toUpperCase() + path.substring(1);
                    voMenu.setComponent(component);
                }
            }

            voMenu.setChildren(new ArrayList<>());
            menuMap.put(menu.getId(), voMenu);
        }

        // 构建树形结构
        for (SysMenuEntity menu : menuList) {
            UserInfoVO.Menu voMenu = menuMap.get(menu.getId());
            Long parentId = menu.getParentId();

            if (parentId == null || parentId == 0) {
                // 如果没有父菜单或父菜单ID为0，则添加到结果列表
                result.add(voMenu);
            } else {
                // 否则添加到父菜单的children列表中
                UserInfoVO.Menu parentMenu = menuMap.get(parentId);
                if (parentMenu != null) {
                    parentMenu.getChildren().add(voMenu);
                }
            }
        }

        return result;
    }

    @Override
    public Map<String, Object> getUserPermissions() {
        Map<String, Object> result = new HashMap<>();

        // 获取当前登录用户ID
        Long userId = StpUtil.getLoginIdAsLong();

        // 1. 查询用户信息
        User user = userMapper.selectOneById(userId);
        if (user == null) {
            throw new RuntimeException("当前用户不存在");
        }

        // 2. 查询用户角色列表
        List<String> roleNames = roleMapper.selectRoleNameListByUserId(userId);
        List<Long> roleIds = roleMapper.selectRoleIdListByUserId(userId);

        // 3. 查询用户所有权限点
        List<SysAclEntity> aclList = new ArrayList<>();
        if (!roleIds.isEmpty()) {
            // 构建查询条件：查找所有角色对应的权限
            QueryWrapper aclQuery = QueryWrapper.create()
                    .select()
                    .from(SysAclEntity.class)
                    .where(SysAclEntity::getId).in(
                            QueryWrapper.create()
                                    .select(SysRoleAcl::getAclId)
                                    .from(SysRoleAcl.class)
                                    .where(SysRoleAcl::getRoleId).in(roleIds)
                    );
            aclList = sysAclMapper.selectListByQuery(aclQuery);
        }

        // 4. 构建权限树结构
        List<Map<String, Object>> permissionTree = buildPermissionTree(aclList);

        // 5. 组装结果
        result.put("userId", userId);
        result.put("username", user.getUsername());
        result.put("realName", user.getRealName());
        result.put("roles", roleNames);
        result.put("permissions", aclList.stream().map(SysAclEntity::getCode).collect(Collectors.toList()));
        result.put("permissionTree", permissionTree);

        return result;
    }

    /**
     * 构建权限树结构
     * @param aclList 权限列表
     * @return 权限树
     */
    private List<Map<String, Object>> buildPermissionTree(List<SysAclEntity> aclList) {
        List<Map<String, Object>> tree = new ArrayList<>();

        // 按类型分组（API、菜单、按钮）
        Map<Integer, List<SysAclEntity>> typeGroup = aclList.stream()
                .collect(Collectors.groupingBy(SysAclEntity::getType));

        // 构建树结构
        for (Map.Entry<Integer, List<SysAclEntity>> entry : typeGroup.entrySet()) {
            Integer type = entry.getKey();
            List<SysAclEntity> perms = entry.getValue();

            Map<String, Object> typeNode = new HashMap<>();
            typeNode.put("type", type);
            typeNode.put("typeName", getTypeName(type));
            typeNode.put("permissions", perms.stream().map(this::convertAclToMap).collect(Collectors.toList()));

            tree.add(typeNode);
        }

        return tree;
    }

    /**
     * 获取权限类型名称
     * @param type 类型值
     * @return 类型名称
     */
    private String getTypeName(Integer type) {
        switch (type) {
            case 1: return "API接口";
            case 2: return "菜单权限";
            case 3: return "按钮权限";
            default: return "其他权限";
        }
    }

    /**
     * 将权限实体转换为Map
     * @param acl 权限实体
     * @return Map格式的权限信息
     */
    private Map<String, Object> convertAclToMap(SysAclEntity acl) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", acl.getId());
        map.put("name", acl.getName());
        map.put("code", acl.getCode());
        map.put("url", acl.getUrl());
        map.put("type", acl.getType());
        return map;
    }
}